
class spwm:
    def __init__(self,pin):
        self.pin = pin

    def __call__(self,Hz):
        self.value(float(Hz))

    def value(self,hz=None):
        if hz: # no 0 !
            use.softpwm[str(self.pin)] = int(1000.0/hz)
        return use.softpwm[str(self.pin)]

    def stop(self):
        del use.softpwm[str(self.pin)]

    async def spwm(self,rise,fall):
        while True:
            pwm = use.softpwm.get( str(self.pin), None)
            #break on low
            if pwm is None:
                break

            for state in (1,0,):
                if state:
                    if rise:rise()
                elif fall:fall()
                self.pin(state)
                await aio.asleep_ms(pwm)

class softpwm(dict):
    spwm = spwm

    def __call__(self,pin,hz,rise=None,fall=None):
        if isinstance(pin,str):
            pin  = gpio(pin,'w',0)
        pin = self.spwm(pin)
        pin.value(hz)
        aio.create_task( pin.spwm(rise,fall))
        return pin

softpwm = softpwm()
use.softpwm = softpwm
del spwm, sys.modules[__name__]
use.gc()
